import { useAntdTable } from "ahooks"
import {
  AntdTableOptions,
  AntdTableResult,
  Data,
  Params,
  Service
} from "ahooks/lib/useAntdTable/types"
import { Badge, TableProps, Tooltip } from "antd"
import { ColumnType } from "antd/lib/table"

type AntdTableExpandResult<TData extends Data, TParams extends Params> = Omit<
  AntdTableResult<TData, TParams>,
  "tableProps"
> & {
  tableProps: TableProps<TData["list"][number]>
}

type AntdTableExpandOptions<
  TData extends Data,
  TParams extends Params
> = AntdTableOptions<TData, TParams> & {
  mergeProps?: Omit<
    TableProps<TData["list"][number]>,
    "pagination" | "onChange"
  > & { pagination?: false }
}

export function useAntdTableExpand<TData extends Data, TParams extends Params>(
  server: Service<TData, TParams>,
  expandOptions?: AntdTableExpandOptions<TData, TParams>
): AntdTableExpandResult<TData, TParams> {
  // 这里可以对columns做一点点处理
  const { mergeProps = {}, ...options } = expandOptions ?? {}
  const tableResult = useAntdTable<TData, TParams>(server, options)

  return {
    ...tableResult,
    tableProps: {
      className: `ym-table${
        mergeProps.className ? " " + mergeProps.className : ""
      }`,
      ...tableResult.tableProps,
      pagination: {
        ...tableResult.tableProps.pagination,
        showTotal: (n) => <>共{n}条</>,
        pageSizeOptions: [10, 15, 20, 30, 40, 50],
        showSizeChanger: true
      },
      scroll: { x: "100%" },
      ...mergeProps
    }
  }
}

/**
 * @desc 做一些antd cloumns 的方便转换
 */

interface expandColumnsType<RecordType> extends ColumnType<RecordType> {
  /**
   * @desc todo 还未进行开发
   */
  valueEnum?: Record<string | number, { text: string; color?: string }>
  valueEnumType?: string
  /**
   * @desc 是否隐藏 true 隐藏
   */
  hidden?: boolean
}

type FirstParams<RecordType> =
  | expandColumnsType<RecordType>[]
  | (() => expandColumnsType<RecordType>[])

export function antdColumnsTransform<RecordType>(
  columns: FirstParams<RecordType>,
  options: { /** @desc 默认拷贝item 的1级属性 */ copyItem?: boolean } = {}
): NonNullable<TableProps<RecordType>["columns"]> {
  if (typeof columns === "function") {
    columns = columns()
  }
  const { copyItem = true } = options
  return columns
    .filter((v) => !v.hidden)
    .map((v) => {
      if (v.ellipsis === true) {
        v.ellipsis = {
          showTitle: false
        }
        PageRender(v, (fn) => {
          return function render(value, record, index) {
            const el = fn(value, record, index)
            if (value) {
              return (
                <Tooltip placement="topLeft" title={value}>
                  <>{el}</>
                </Tooltip>
              )
            } else {
              return el
            }
          }
        })
      }
      if (v.valueEnum) {
        const valueEnumType = v.valueEnumType ?? "cicle"
        const valueEnum = v.valueEnum
        PageRender(v, (fn) => {
          return function render(value, record, index) {
            const item = valueEnum[value] ?? {}
            const el = fn(item.text, record, index)
            if (value !== undefined || value !== null) {
              if (valueEnumType === "cicle") {
                return (
                  <Badge
                    key={item.color}
                    color={item.color}
                    text={<>{el}</>}
                  ></Badge>
                )
              } else {
                return el
              }
            } else {
              return el
            }
          }
        })
      }
      if (copyItem) {
        return { ...v }
      } else {
        return v
      }
    })
}

type columnItem<RecordType> = NonNullable<
  TableProps<RecordType>["columns"]
>[number]
function PageRender<RecordType>(
  item: columnItem<RecordType>,
  renderFn: (
    render: NonNullable<columnItem<RecordType>["render"]>
  ) => NonNullable<columnItem<RecordType>["render"]>
) {
  if ((item as ColumnType<RecordType>).dataIndex) {
    if (typeof item.render === "undefined") {
      item.render = renderFn((value) => {
        return value
      })
    } else {
      item.render = renderFn(item.render)
    }
  }
}
